﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace Autorun
{
	public partial class ServerDashboard : Autorun.PaneBase
	{
		#region "Private members"
		private const string ICO_REFRESH = "icoRefresh";
		#endregion

		#region "Constructors and Form's Events Handlers"
		public ServerDashboard()
		{
			InitializeComponent();
		}

		public override bool Initialize(IPresenter sender, ShowPaneEventArgs e)
		{
			_parent = sender;

			if ((e != null) && (e.Args != null) && (e.Args.Length != 0))
				if (e.Args[0] is ServerManagement)
					_proxy = (ServerManagement)e.Args[0];
				else
					_proxy = null;
			else
				_proxy = null;

			processorMonitor1.SetData(_proxy);

			LoadIcons();
			mnuRefresh.Image = myImages.Images[ICO_REFRESH];
			RefreshServerInformation();

			return true;
		}

		public override void Terminate()
		{
			if (_proxy != null)
			{
				try
				{
					_proxy.Service.OnNotify -= Service_OnNotify;
					_proxy.Service.OnStart -= Service_OnStart;
					_proxy.Service.OnStop -= Service_OnStop;
				}
				catch { }
				//myProperty.SelectedObject = null;
			}
			base.Terminate();
		}
		#endregion

		#region "Methods"
		private void LoadIcons()
		{
			myImages.Images.Clear();
			myImages.Images.Add(ICO_REFRESH, Properties.Resources.icoRefresh);
		}

		#region "Server Events Handlers"
		void Service_OnNotify(object sender, NotifyEventArgs e)
		{
			RefreshInformation();
		}

		void Service_OnStop(object sender, StopEventArgs e)
		{
			RefreshInformation();
		}

		void Service_OnStart(object sender, StartEventArgs e)
		{
			RefreshInformation();
		}
		#endregion

		private void RefreshServerInformation()
		{
			if (_proxy == null)
			{
				Caption = "Not connected";
			}
			else
			{
				Caption = string.Format("{0}: Information summary", _proxy.Information.MachineName);

				try
				{
					_proxy.Service.OnNotify += new NotifyEventHandler(Service_OnNotify);
					_proxy.Service.OnStart += new StartEventHandler(Service_OnStart);
					_proxy.Service.OnStop += new StopEventHandler(Service_OnStop);
					// The event handler has been added, no need to use the timer
					myTimer.Enabled = false;
				}
				catch 
				{
					// The event handler cannot be used on remote servers, use a timer instead
					myTimer.Enabled = true;
				}
				pbRunning.Maximum = _proxy.Configuration.ThreadPoolSize;

				RefreshInformation();
			}
		}

		private void RefreshInformation()
		{

			if (_proxy == null) return;

			pbRunning.Value = _proxy.Service.RunningTaskCount;
			lblRunningCount.Text = string.Format("{0}/{1}", pbRunning.Value, pbRunning.Maximum);

			if (lblDay.Text != _proxy.Scheduler.LastPlannedDay.ToString())
			{
				txtDay.Text = _proxy.Scheduler.LastPlannedDay.ToString();

				if (pbWaiting.Value > _proxy.Scheduler.WaitingTasksCountMax)
					pbWaiting.Value = _proxy.Scheduler.WaitingTasksCountMax;
				pbWaiting.Maximum = _proxy.Scheduler.WaitingTasksCountMax;

				if (pbShutdown.Value > _proxy.Scheduler.WaitingTasksOnShutdownCountMax)
					pbShutdown.Value = _proxy.Scheduler.WaitingTasksOnShutdownCountMax;
				pbShutdown.Maximum = _proxy.Scheduler.WaitingTasksOnShutdownCountMax;
			}

			try
			{
				if (pbWaiting.Value != _proxy.Scheduler.WaitingTasksCount)
					pbWaiting.Value = _proxy.Scheduler.WaitingTasksCount;
			}
			catch { }
			lblWaitingCount.Text = string.Format("{0}/{1}", pbWaiting.Value, pbWaiting.Maximum);

			pbShutdown.Value = _proxy.Scheduler.WaitingTasksOnShutdownCount;
			lblShutdownCount.Text = string.Format("{0}/{1}", pbShutdown.Value, pbShutdown.Maximum);

			DateTime dt = _proxy.Scheduler.NextTask;
			txtTask.Text = _proxy.Scheduler.NextTask.ToString("HH:mm");

			Refresh();
		}

		private void RefreshTaskList()
		{
			SortedList<string, TaskContext> tasks;
			ListViewItem lvi;

			// === Display running tasks ===========================================
			lock (this)
			{
				tasks = _proxy.Service.RunningTasks;
				myTasks.Items.Clear();
				foreach (KeyValuePair<string, TaskContext> item in tasks)
				{
					lvi = myTasks.Items.Add(item.Value.Caption, 0);
					lvi.Tag = item.Key;
					lvi.SubItems.Add(item.Value.StartedOn.ToString());
				}
				myTasks.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
				myTasks.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
			}
		}
		#endregion

		#region "Controls Events Handlers"
		private void mnuRefresh_Click(object sender, EventArgs e)
		{
			RefreshInformation();
			RefreshTaskList();
		}

		private void myTimer_Tick(object sender, EventArgs e)
		{
			RefreshInformation();
		}

		private void myPopup_Opening(object sender, CancelEventArgs e)
		{
			if (myTasks.SelectedItems.Count != 0)
				mnuKill.Enabled = true;
			else
				mnuKill.Enabled = false;
		}

		private void mnuKill_Click(object sender, EventArgs e)
		{
			string key;

			if (myTasks.SelectedItems.Count != 0)
#if !DEBUG
				if (MessageBox.Show("Do you really want to kill this task?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
#endif
				{
					key = myTasks.SelectedItems[0].Tag.ToString();
					_proxy.Service.KillTask(key);
				}
			RefreshTaskList();
		}
		#endregion
	}
}
